package com.zhangyj.action;

import java.io.IOException;
import java.io.Serializable;
import java.io.Writer;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;

import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.zhangyj.entitis.SystemParam;
import com.zhangyj.impl.UserContext;
import com.zhangyj.security.AuthemticationFactory;
import com.zhangyj.security.AuthenticationException;
import com.zhangyj.security.IAuthentication;
import com.zhangyj.security.Permission;
import com.zhangyj.util.Tools;

/**
 * 本类为所有逻辑的基类。<br/>
 * 并不是线程安全类，并且是多线程调用。注意内部的成员变量的使用
 * 
 * @author zhangyj
 * 
 */
public abstract class AbstractAction implements Serializable {

	/**
	 * 
	 */
	private static final long serialVersionUID = 6804379478938682044L;
	protected String validateFailed = "";
	protected ServletContext context = null;
	protected HttpServletRequest request = null;
	protected HttpServletResponse response = null;

	/**
	 * 默认不做任何事情，在类初始化的时候调用。可以在子类的初始化时做一些初始化的工作。
	 */
	public void init(ServletContext context) {
		this.context = context;
	}

	/**
	 * 如果返回true验证成功，false反之。<br>
	 * 做一般的验证工作，父类只能返回true，具体的事情由子类完成。
	 * 
	 * @param request
	 * @param response
	 * @return
	 * @throws ServletException
	 * @throws IOException
	 */
	public boolean validate() throws Exception {
		return true;
	}

	/**
	 * 权限验证
	 * 
	 * @param request
	 * @param permissionType
	 *            权限类型update insert...
	 * @throws AuthenticationException
	 */
	public void validatePermission(int permissionType) throws AuthenticationException {
		SystemParam systemParam = SystemParam.getSystemParam(request);
		if (systemParam.getFunctionId() == -1) {
			return;
		}
		IAuthentication auth = AuthemticationFactory.getFucAuth();
		UserContext userContext = UserContext.getUserContext(request);
		Permission permission = new Permission();
		permission.setAction(permissionType);
		permission.setFuncId(systemParam.getFunctionId());
		auth.validate(userContext.getUserid(), permission);
	}

	protected String getParameter(String name, String defaultVal) {
		return Tools.getParameter(request, name, defaultVal);
	}

	protected int getIntParameter(String name, int defaultVal) {
		return Tools.getIntParameter(request, name,defaultVal);
	}

	protected String getParameter(String name) {
		return getParameter(name, null);
	}

	protected int getIntParameter(String name) {
		return getIntParameter(name, -1);
	}

	protected Object getAttribute(HttpServletRequest request, String param) {
		return getAttribute(request, param, "");
	}

	protected Object getAttribute(HttpServletRequest request, String param, Object defaultVal) {
		Object obj = request.getAttribute(param);
		if (obj == null) {
			obj = defaultVal;
		}
		return obj;
	}

	/**
	 * 最终的逻辑工作，由子类完成
	 * 
	 * @param request
	 * @param response
	 * @return 要转向的页面路径 有两个内置的变量seccess 和 failed
	 * @throws ServletException
	 * @throws IOException
	 */
	final public Object doAction() throws Exception {
		String action = getParameter( "action", "login");
		Method[] ms = this.getClass().getMethods();
		for (int i = 0; i < ms.length;i++) {
			Method m = ms[i];
			RequestMethod ra = m.getAnnotation(RequestMethod.class);
			if (ra != null&& ra.name().equals(action)) {
				return m.invoke(this, (Object[])null);
			}
		}
		return null;
	}

	protected void destroy() {
	}
	protected void writerBackJSON(String jsonStr) throws IOException{
		response.setContentType("application/json;charset=UTF-8");
		Writer writer = response.getWriter();
		writer.append(jsonStr);
	}
	public void success( String msg, Object obj) throws IOException {
		response.setContentType("application/json;charset=UTF-8");
		Writer writer = response.getWriter();
		writer.append("{\"success\":true");
		if (msg != null && msg.length() > 0) {
			writer.append(",\"msg\":\"").append(Tools.builderJSONString(msg)).append("\"");
		}
		if (obj != null) {
			writer.append(",\"result\":").append(Tools.object2jsonStr(obj));
		}
		writer.append("}");
	}
	public void fail( Exception e) throws IOException {
		response.setContentType("application/json;charset=UTF-8");
		response.setStatus(500);
		Writer writer = response.getWriter();
		writer.append(e.getMessage());
	}
	protected Map<String, Object> buildPageMap() {
		Map<String, Object> page = new HashMap<String, Object>();
		page.put("offset", getIntParameter("start", 0));
		page.put("size", getIntParameter("count", 0));
		return page;
	}
	
}
